Overview of Error Management
Let’s learn about error management in clean architecture.
Overview#
In every software project, a large part of the code is dedicated to error management. This part of the code has to be infallible. Yet, more often than not, we find that we’ve left out cases that give errors, or we’ve provided a condition that we thought would never fail but does.
In clean architecture, the main process is the creation of use cases and their execution. As we can expect, this is also the main source of errors. So, the use cases layer is where we have to implement error management. This isn’t to say that errors can’t also come from the domain models layer. However, since those models are created by the use cases, the errors that aren’t managed by the models themselves are automatically treated as errors of the use cases.
Request and Responses#
We can divide the error management code into two different sections:
- The first section represents and manages requests—that is, the input data that reaches our use case.
- The second section covers how we return results from the use case through responses or the output data.
These two concepts shouldn’t be confused with HTTP requests and responses, even though there are similarities between them. We are now considering how data is passed to and received from use cases and how errors can be managed. This isn’t related to another possible use of this architecture, which is to expose an HTTP API.
Request and response objects#
Request and response objects are an important part of clean architecture because they transport call parameters, inputs, and results from outside the application into the use cases layer.
More specifically, requests are objects created from incoming API calls. They deal with things like incorrect values, missing parameters, wrong formats, and so on. On the other hand, responses not only have to contain the actual results of the API calls but should also be able to represent error cases and deliver rich information on what happened.
The implementation of request and response objects depends completely on our discretion. Clean architecture says nothing about it. The decision on how to pack and represent data is up to us.
Supporting filters#
In order to start working on possible errors and to develop an understanding of how to manage them, we’re going to expand room_list_use_case to support filters. These filters can be used to select a subset of the Room objects in storage.
For example, the filters could be represented by a dictionary that contains attributes of the Room model and the logic that we want to apply to them. Once we accept such a rich structure, we open our use case to the following errors:
- Attributes that don’t exist in the model.
- Thresholds of the wrong type.
- Filters that make the storage layer crash. All of these considerations have to be taken into account by the use case.
Basic structure#
We can implement structured requests before we expand the use case to accept filters.
Handle requests#
In order to handle requests, we only need the RoomListRequest class. This class can be initialized without parameters. Let’s create the tests/requests/test_room_list.py file and put a test for this object in it.
Although right now, this request object is empty, it’ll come in handy as soon as we start having parameters for the list use case. The code of the RoomListRequest class is as follows:
Write responses#
The response object is also very simple because, for the moment, we only need to return a successful result. Unlike the request, the response isn’t linked to any particular use case, so we can name the test file tests/test_responses.py. The code for the response is as follows:.
The actual response object is in the rentomatic/responses.py file, as shown below:
With the help of these two objects, we’ve laid down the foundations for a richer management of the input and outputs of the use case, especially in the case of error conditions.
Updated code#
In the code editor, we’ve updated the files with the new code.
/
Web Server Gateway Interface (WSGI)
Requests and Responses in a Use Case